<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>【规约】 MySQL 数据库篇 - Zexun Luo | 罗泽勋</title>
    <meta property="og:title" content="【规约】 MySQL 数据库篇 - Zexun Luo | 罗泽勋">
    
    <meta name="twitter:card" content="summary">

    
      
    

    
      
      <meta property="description" content="“码出高效，码出质量”。本文整理了比较常见的 MySQL 数据库编程规范，主要来源于《阿里巴巴 Java 开发手册》。
[&amp;hellip;] 1.【强制】表达是与否概念的字段，必须使用 is_xxx 的方式命名，数据类型是 unsigned tinying(1 表示是，0 表示否)。
说明：任何字段如果为非负数，必须是 unsigned。
注意：POJO 类中任何布尔类型的变量，都不要加 is 前 &amp;hellip;">
      <meta property="og:description" content="“码出高效，码出质量”。本文整理了比较常见的 MySQL 数据库编程规范，主要来源于《阿里巴巴 Java 开发手册》。
[&amp;hellip;] 1.【强制】表达是与否概念的字段，必须使用 is_xxx 的方式命名，数据类型是 unsigned tinying(1 表示是，0 表示否)。
说明：任何字段如果为非负数，必须是 unsigned。
注意：POJO 类中任何布尔类型的变量，都不要加 is 前 &amp;hellip;">
      
    

    
    
    
    <meta name="twitter:image" content="/images/logo.png">
    
    

    

    
    

    <link rel="stylesheet" href="/css/style.css" />
    <link rel="stylesheet" href="/css/fonts.css" />
    
<link rel="stylesheet" href="/css/custom.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer@1.10.0/dist/APlayer.min.css">  

  </head>

  
  <body class="post">
    <div id="pjax-content">
    <header class="masthead">
      

<h1><a href="/"><img src="/images/logo.png" alt="Zexun Luo" /></a></h1>



      <nav class="menu">
  <ul>
  
  
  <li><a href="/">主页</a></li>
  
  <li><a href="/about/">关于</a></li>
  
  <li><a href="/blog/">日志</a></li>
  
  <li><a href="/post/">技术</a></li>
  
  

  </ul>
</nav>

    </header>
    <article class="main">
      <header class="title">
      
<h1>【规约】 MySQL 数据库篇</h1>


<h3>
2021-05-28</h3>

<hr>


      </header>



<h3 id="前言">前言</h3>
<p>“码出高效，码出质量”。本文整理了比较常见的 MySQL 数据库编程规范，主要来源于《阿里巴巴 Java 开发手册》。</p>
<h3 id="一建表规约">(一)建表规约</h3>
<p>1.【强制】表达是与否概念的字段，必须使用 is_xxx 的方式命名，数据类型是 unsigned tinying(1 表示是，0 表示否)。<br>
说明：任何字段如果为非负数，必须是 unsigned。<br>
注意：POJO 类中任何布尔类型的变量，都不要加 is 前缀，所以，需要在 <resultMap> 设置从 is_xxx 到 Xxx 的映射关系。数据库表示是与否的值，使用 tinyint 类型，坚持 is_xxx 的命名方式是为了明确其取值含义与范围。<br>
正例：表达逻辑删除的字段名 is_deleted，1 表示删除，0 表示未删除。</p>
<p>2.【强制】表名、字段名必须使用小写字母或数字，禁止出现数字开头，禁止两个下划线中间只出现数字。数据库字段名的修改代价很大，因为无法进行预发布，所以字段名称需要慎重考虑。<br>
说明:MySQL 在 Windows 下不区分大小写，但在 Linux 下默认是区分大小写。因此，数据库名、表名、字段名，都不允许出现任何大小写字母，避免节外生枝。<br>
正例：aliyun_admin, rdc_config, level3_name
反例：AliyunAdmin, rdcConfig, level_3_name</p>
<p>3.【强制】表明不使用复数名词。
说明：表名应该仅仅表示表里面的实体内容，不应该表示实体数量，对应于 DO 类名也是单数形式，符合表达习惯。</p>
<p>4.【强制】主键索引名为 pk_字段名；唯一索引名为 uk_字段名；普通索引名则为 idx_字段名。<br>
说明：pk_ 即 primary key；uk_ 即 unique key；idx_ 即 index 的简称。</p>
<p>5.【小数类型】为 decimal，禁止使用 float 和 double。<br>
说明：float 和 double 在存储的时候，存在精度损失的问题，很可能在值的比较时，得不到正确的结果。如果存储的数据范围超 decimal 的范围，建议将数据拆成整数和小数分开存储。</p>
<p>6.【强制】如果存储的字符串长度几乎相等，使用 char 定长字符串类型。</p>
<p>7.【强制】varchar 是可变字符串，不与先分配存储控件，长度不要超过 5000，如果存储长度大于此值，定义字段类型为 text,独立出来一张表，用主键来对应，避免影响其他字段索引效率。</p>
<p>8.【强制】表必备三字段：id, gmt_create, gmt_modified。<br>
说明：其中 id 必为主键，类型为 bigint unsigned、单表自增、步长为 1。gmt_create，gmt_modified 的类型均为 datetime 类型，前者现在时表示主动创建，后者过去分词表示被动更新。</p>
<p>9.【推荐】表的命名最好是加上”业务名称_表的作用“。<br>
正例：alipay_task   /   force_project   /   trade_config</p>
<p>10.【推荐】库名与应用名称尽量一致。</p>
<p>11.【推荐】字段允许适当冗余，以提高查询性能，但必须考虑数据一致。冗余字段应遵循：<br>
1）不是频繁修改的字段。<br>
2）不是 varchar 超长字段，更不能是 text 字段。<br>
正例：商品类目名称使用频率高，字段长度短，名称基本一成不变，可在相关联的表中冗余存储类目名称，避免关联查询。</p>
<p>12.【参考】合适的字符存储长度，不但节约数据库表空间、节约索引存储，更重要的是提升检索速度。<br>
正例：  人  150岁之内   tinyint unsigned    1字节   无符号值：0 到 255<br>
龟  数百岁  smallint unsigned   2字节   无符号值：0 到65535</p>
<h3 id="二索引规约">（二）索引规约</h3>
<p>1.【强制】业务上具有唯一特性的字段，即使是多个字段的组合，也必须建成唯一索引。<br>
说明：不要以为唯一索引影响了 insert 速度，这个速度的损耗可以忽略，但提高查找速度是明显的；另外，只要没有唯一索引，必定有脏数据产生（墨菲定律）。</p>
<p>2.【强制】超过三个表禁止 join。需要 join 的字段，数据类型必须绝对一致；多表关联查询时，保证被关联的字段有索引。<br>
说明：join 需要注意表索引、SQL 性能。</p>
<p>3.【强制】在 varchar 字段上建立索引时，必须根据文本区分度指定索引长度。</p>
<p>4.【强制】页面搜索严禁左模糊或者全模糊，如果需要请走搜索引擎来解决。<br>
说明：索引文件具有 B-Tree 的最左前缀匹配特性，如果左边的值未确定，那么无法使用此索引。</p>
<p>5.【推荐】利用覆盖索引来进行查询操作，避免回表。</p>
<p>6.【参考】创建索引时避免有如下极端误解：<br>
1）宁滥勿缺。认为一个查询就需要建一个索引。<br>
2）宁缺毋滥。认为索引会消耗空间、严重拖慢更新和新增速度。<br>
3）抵制唯一索引。认为业务的唯一性一律需要在应用层通过”先查后插“方式解决。</p>
<h3 id="三sql-语句">（三）SQL 语句</h3>
<p>1.【强制】不要使用 count(列名) 或 count(常量) 来替代 count(*)。</p>
<p>2.【强制】使用 ISNULL() 来判断是否为 NULL 值。</p>
<p>3.【强制】不得使用外键和级联，一切外键概念不必在应用层解决。
说明：外键与级联更新使用于单机低并发，不适合分布式、高并发集群；级联更新时强阻塞，存在数据库过呢更新风暴的风险；外键影响数据库的插入速度。</p>
<p>4.【推荐】尽量避免 in 操作，若使用也需评估 in 后边的集合元素数量，控制在 1000 个之内。</p>


  
  <nav class="post-nav">
    <span class="nav-prev">&larr; <a href="/post/zxhan/">[做点有趣的]C&#43;&#43;做一个哈夫曼压缩软件</a></span>
    <span class="nav-next"><a href="/post/javacodingguidelines/">【规约】 Java 编程篇</a> &rarr;</span>
  </nav>
  <script type="text/javascript">
  document.addEventListener('keyup', function(e) {
    if (e.target.nodeName.toUpperCase() != 'BODY') return;
    var url = false;
    if (e.which == 37) {  
      
      url = '\/post\/zxhan\/';
      
    } else if (e.which == 39) {  
      
      url = '\/post\/javacodingguidelines\/';
      
    }
    if (url) window.location = url;
  });
  </script>
  
  </article>
  </div>
  <footer>
  
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="/js/jquery.pjax.js"></script>
<script src="/js/pjax.config.js"></script>

<div class="music">
<div id="player" class="aplayer"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/aplayer@1.10.0/dist/APlayer.min.js"></script>  

<script type="text/javascript">
const ap = new APlayer({
    container: document.getElementById('player'),
    order: 'random',
    listFolded: true,
    listMaxHeight: 90,
    theme:	'#b7daff',
    audio: [
    {
        name: 'きこえるかしら',
        artist: '大和田りつこ',
        url: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/music/赤毛のアンOP_きこえるかしら_大和田りつこ.mp3',
        cover: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/image/赤毛のアンOP_きこえるかしら_大和田りつこ.jpeg'
      },
      {
        name: 'まっててごらん',
        artist: '大杉久美子',
        url: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/music/大杉久美子_ネリー・シュワルツ_まっててごらん.mp3',
        cover: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/image/大杉久美子_ネリー・シュワルツ_まっててごらん.png'
      },
      {
        name: 'ペリーヌ物語',
        artist: '片头曲和片尾曲',
        url: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/music/世界名作劇場_ペリーヌ物語_OP_ED.mp3',
        cover: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/image/世界名作劇場_ペリーヌ物語_OP_ED.jpg'
      },
      {
        name: 'ほほえみの魔法',
        artist: 'トラップ一家物語',
        url: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/music/Trapp_Family_Story_Hohoemi_no_mahou_ほほえみの魔法_Smil.mp3',
        cover: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/image/Trapp_Family_Story_Hohoemi_no_mahou_ほほえみの魔法_Smil.jpg'
      },
      {
        name: 'It is a Small world',
        artist: 'Disney Classics',
        url: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/music/Disney_Classics_It_s_a_Small_World_It_s_a_Small.mp3',
        cover: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/image/Disney_Classics_It_s_a_Small_World_It_s_a_Small.jpg'
      },
      {
        name: 'Forrest Gump Suite',
        artist: 'Alan Silvestri',
        url: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/music/Alan_Silvestri_Forrest_Gump_Suite2.mp3',
        cover: 'https://cdn.jsdelivr.net/gh/lzxqaq/jsdelivr@master/image/Alan_Silvestri_Forrest_Gump_Suite.jpeg'
      },





  ]
});
</script>




<script async src="/js/fix-toc.js"></script>

<script async src="/js/center-img.js"></script>

<script async src="/js/right-quote.js"></script>

<script async src="/js/no-highlight.js"></script>

<script async src="/js/fix-footnote.js"></script>

<script async src="/js/math-code.js"></script>

<script async src="/js/external-link.js"></script>

<script async src="/js/alt-title.js"></script>

<script async src="/js/header-link.js"></script>




  

  
  <hr>
  <div class="copyright">© <a href="/">Zexun Luo</a> 2020 - 2021</div>
  
  </footer>
  
  </body>
</html>

